<template>
  <vxe-modal
    ref="vueModel"
    height="500"
    :value="isShow"
    :loading="loading"
    width="800"
    show-footer
    title="批量编辑"
    remember
    show-zoom
    resize
    fullscreen
    @close="close"
  >
    <template #default>
      <vxe-table
        ref="xTable"
        row-id="id"
        auto-resize
        border
        height="auto"
        resizable
        :data="bodys"
      >
        <template v-for="item in headers">
          <table-col
            v-if="item.children && item.children.length > 0"
            :key="item.id + ''"
            :col-header="item"
            show-overflow-tooltip
          />
          <template v-else-if="item.systemVariablesName === 'TableRN'">
            <vxe-table-column
              :key="item.id"
              type="seq"
              :width="item.width || 60"
              :title="item.title"
              :field="item.dataIndex"
              :show-overflow="item.ellipsis ? 'ellipsis' : 'tooltip'"
              :align="item.align || 'center'"
            />
          </template>
          <template v-else>
            <vxe-table-column
              :key="item.id"
              :field="item.dataIndex"
              :show-overflow="item.ellipsis ? 'ellipsis' : 'tooltip'"
              :min-width="item.width || 200"
              :header-align="item.align || 'center'"
              :align="item.align || 'center'"
              :fixed="item.fixed === ' ' ? '' : item.fixed"
            >
              <template #header>
                <span>{{ item.title }}</span>
                <i
                  :class="['el-icon-s-open',item.dataIndex===editCellInfo.editDataIndex && 'active-edit']"
                  @click="editBrush(item.dataIndex)"
                />
              </template>
              <template slot-scope="scope">
                <div
                  v-if="
                    item.componentType === 'text'"
                >
                  {{ scope.row[item.dataIndex] }}
                </div>
                <el-input
                  v-else-if="item.componentType === 'input'"
                  v-model="scope.row[item.dataIndex]"
                  :placeholder="item.promptText || '请输入' + item.title"
                  :type="item.isNumber ? 'Number' : 'text'"
                  :readonly="!Number(item.edit)"
                  @change="value => inputChange(item, value, scope.rowIndex)"
                />
                <!-- 时间选择器 -->
                <time-picker
                  v-else-if="dataPicker(item)"
                  v-model="scope.row[item.dataIndex]"
                  :type="dataPicker(item).type"
                  :disabled="item.edit === 0"
                  :value-format="dataPicker(item).format"
                  :placeholder="item.promptText || '请选择'"
                  :personal-style="{
                    currentBorderRadius: '6px'
                  }"
                  @change="(value)=>dateChange(item, value)"
                  @blur="
                    () =>
                      getUrlRequire(
                        item,
                        scope.row[item.dataIndex],
                        scope.rowIndex
                      )
                  "
                />
                <!-- 下拉框 -->
                <Select-Url
                  v-else-if="
                    ['select', 'enterpriseIn', 'enterpriseList'].includes(
                      item.componentType
                    )
                  "
                  ref="selectUrl"
                  :select-value="scope.row[item.dataIndex]"
                  :placeholder="item.promptText || '请选择'"
                  :item="item"
                  :disabled="!Number(item.edit)"
                  style="width: 100%;"
                  :data-dataIndex="item.dataIndex"
                  @change="v => selectChangeData(v, scope, item)"
                  @changeItemOption="changeItemOption"
                />
                <SelectTree
                  v-else-if="
                    [
                      'treeSelect',
                      'treeSelectBot',
                      'enterpriseListTree',
                      'enterpriseInTree'
                    ].includes(item.componentType)
                  "
                  :placeholder="item.promptText || '请选择'"
                  :select-value="scope.row[item.dataIndex]"
                  :item="item"
                  :disabled="!Number(item.edit)"
                  @changeData="data => treeSelectChangeData(data, scope, item)"
                />
                <!-- 输入&下拉 -->
                <transition
                  v-else-if="item.componentType === 'toggleInputSelect'"
                  mode="out-in"
                  name="toggleIS"
                >
                  {{ item.myToggleFlag }}
                  <el-input
                    v-if="item.myToggleFlag"
                    ref="innerOper"
                    v-model="scope.row[item.dataIndex]"
                    :placeholder="item.promptText || '请输入'"
                    :class="{'myEllipsis': item.ellipsis === 1}"
                    :disabled="item.edit === 0"
                    style="width: 100%;height: 100%;"
                    :data-dataIndex="item.dataIndex"
                    :title="scope.row[item.dataIndex]"
                    :type="item.isNumber === 1 ? 'number' : 'text'"
                    @change="v => inputChange(item, v, scope.rowIndex)"
                  >
                    <template #prefix>
                      <div class="prefix_icon" @click="toggleFlag(item)">
                        <div class="prefix_icon_bg" />
                        <div>切换</div>
                        <div>选择</div>
                      </div>
                    </template>
                  </el-input>

                  <Select-Url
                    v-else
                    ref="selectUrl"
                    :title="scope.row[item.dataIndex]"
                    :class="{'myEllipsis': item.ellipsis === 1}"
                    :placeholder="item.promptText || '请选择'"
                    :item="item"
                    :disabled="item.edit === 0"
                    style="width: 100%;height: 100%;"
                    :data-dataIndex="item.dataIndex"
                    :select-value="scope.row[item.dataIndex]"
                    @change="v => selectChangeData(v, scope, item)"
                    @changeItemOption="changeItemOption"
                    @toggleChangeComponent="toggleFlag"
                  >
                    <template #prefix>
                      <div class="prefix_icon" @click="toggleFlag(item)">
                        <div class="prefix_icon_bg" />
                        <div>切换</div>
                        <div>输入</div>
                      </div>
                    </template>
                  </Select-Url>
                </transition>
                <div v-else>{{ scope.row[item.dataIndex] }}</div>
              </template>
            </vxe-table-column>
          </template>
        </template>
      </vxe-table>
    </template>
    <template slot="footer">
      <vxe-button @click="close">取 消</vxe-button>
      <vxe-button status="primary" @click="handleOk">确 定</vxe-button>
    </template>
  </vxe-modal>
</template>

<script>
import TimePicker from '@/components/CommonForm/components/TimePicker';
import SelectUrl from '@/components/CommonForm/components/SelectUrl';
import SelectTree from '@/components/CommonForm/components/SelectTree';
import { dealRequestData } from '@/components/CommonForm/common';
import { getCommonData } from '@/api/reportCenter';
import TableCol from './TableCol.vue';
import { digitUppercase } from '@/utils/utils';
import { saveDynamicForm } from '@/api/formConfig';
import _ from 'lodash';
export default {
  name: 'TableComponent',
  components: {
    SelectUrl,
    SelectTree,
    TimePicker,
    TableCol
  },
  props: {
    isShow: {
      type: Boolean,
      default: false
    },
    headers: {
      type: Array,
      default: () => ([])
    },
    body: {
      type: Array,
      default: () => ([])
    },
    tableId: {
      type: [Number, String],
      default: undefined
    }
  },
  provide() {
    return {
      bodysData: () => this.bodys,
      upperFieldList: () => this.upperFieldList,
      isUpperList: () => this.isUpperList,
      editCellInfoPro: () => this.editCellInfo
    };
  },
  data() {
    return {
      oldBody: [],
      bodys: [],
      upperFieldList: [],
      isUpperList: [],
      // 必填字段
      requireArr: [],
      loading: false,
      // 特殊的请求(有other)
      otherUrlRequire: [],
      // 特殊的请求需要的dataIndex(提供者)
      otherUrlDataindex: [],
      otherUrlParams: [],
      editCellInfo: {
        editDataIndex: '',
        editDataIndexValue: undefined
      }

    };
  },
  watch: {
    isShow(value) {
      if (value) {
        // 先显示dome再加载数据
        this.loading = true;
        this.getUpperFieldList();
        // this.$nextTick(() => {
        //   this.loading = false;
        //   this.bodys = _.cloneDeep(this.body);
        //   this.oldBody = _.cloneDeep(this.body);
        // });
        setTimeout(() => {
          this.bodys = _.cloneDeep(this.body);
          this.oldBody = _.cloneDeep(this.body);
          this.$nextTick(() => {
            this.loading = false;
          });
        }, 200);
      }
    },
    headers(value) {
      this.requireArr = [];
      value.forEach(item => {
        if (item.isRequired) {
          const { dataIndex, title } = item;
          this.requireArr.push({
            dataIndex,
            title
          });
        }
      });
    }
  },
  methods: {
    getUpperFieldList() {
      this.body.forEach(item => {
        if (Number(item.isUpper) === 1) {
          this.isUpperList.push(item.dataIndex);
          this.upperFieldList.push(item.upperField);
        }
      });
    },
    editCellChange(dataIndex, value) {
      this.editCellInfo.editDataIndexValue = value;
      this.editCellInfo.editDataIndex = dataIndex;
    },
    // tableFocus(item, value) {
    //   const { dataIndex } = item;
    //   this.editDataIndex = dataIndex;
    //   this.editDataIndexValue = value;
    //   console.log(value);
    // },
    editBrush(dataIndex) {
      // dataIndex === this.editDataIndex && this.bodys.forEach(i => {
      //   i[dataIndex] = this.editDataIndexValue;
      // });
      if (dataIndex === this.editCellInfo.editDataIndex) {
        // this.bodys = this.bodys.map(i => i[dataIndex] = this.editDataIndexValue);
        for (let i = 0; i < this.bodys.length; i++) {
          this.bodys[i][dataIndex] = this.editCellInfo.editDataIndexValue;
        }
      }
    },
    dateChange({ dataIndex }, value) {
      this.editCellChange(dataIndex, value);
    },
    inputChange(item, value, index) {
      const { dataIndex } = item;
      this.editCellChange(dataIndex, value);
      this.bodys[index][dataIndex] = Number(item.isNumber)
        ? Number(value)
        : value;
      // 是否存在金额大写
      const i = this.upperFieldList.findIndex(
        k => k === dataIndex
      );
      if (i !== -1) {
        this.bodys[index][
          this.isUpperList[i]
        ] = digitUppercase(this.bodys[index][dataIndex]);
      }
    },
    // 时间选择器类型
    dataPicker(item) {
      const { componentType } = item;
      const typesMap = {
        yearDateSelect: {
          format: 'yyyy',
          type: 'year'
        },
        monthDateSelect: {
          format: 'yyyy-MM',
          type: 'month'
        },
        dayDateSelect: {
          format: 'yyyy-MM-dd',
          type: 'date'
        },
        monthDateSelectRange: {
          format: 'yyyy-MM',
          type: 'monthrange'
        },
        dayDateSelectRange: {
          format: 'yyyy-MM-dd',
          type: 'daterange'
        }
      };

      if (componentType in typesMap) {
        return typesMap[componentType];
      } else {
        return false;
      }
    },

    // 树状下拉选择(联动)
    treeSelectChangeData(treeData, scope, item) {
      const { data, node } = treeData;
      const { rowIndex } = scope;
      const { dataIndex, selectViewOptions, linkageFields } = item;
      // const { renderValue } = selectViewOptions;
      const { renderKey } = selectViewOptions;
      this.bodys[rowIndex][dataIndex] = data[renderKey];
      this.editCellChange(dataIndex, data[renderKey]);
      const nodeArr = [];
      const AddNodeshift = arr => {
        if (arr.parent) {
          nodeArr.unshift(arr.data);
          AddNodeshift(arr.parent);
        }
      };
      AddNodeshift(node);
      linkageFields.length &&
        linkageFields.forEach(itemC => {
          if (!itemC.level) {
            this.bodys[rowIndex][itemC.key] = data[itemC.value];
          } else {
            this.bodys[rowIndex][itemC.key] =
              nodeArr[itemC.level - 1][itemC.value];
          }
        });
      this.$forceUpdate();
    },

    // 下拉联动,data为选择的option
    selectChangeData(data, scope, item) {
      const { rowIndex } = scope;
      const { dataIndex, selectViewOptions, linkageFields } = item;
      // const { renderValue } = selectViewOptions;
      const { renderKey } = selectViewOptions;
      this.bodys[rowIndex][dataIndex] = data[renderKey];
      this.editCellChange(dataIndex, data[renderKey]);

      linkageFields.length &&
        linkageFields.forEach(itemC => {
          const linkObj = this.headers.find(
            v => v.dataIndex === itemC.key
          );
          let componentType, focusUrlParams;
          linkObj &&
            (componentType = linkObj.componentType) &&
            (focusUrlParams = linkObj.focusUrlParams);
          if (focusUrlParams && focusUrlParams.other) {
            this.getUrlRequire(item, data[itemC.value], rowIndex);
            return;
          }
          if (componentType === 'select' && linkObj && !linkObj.focusUrl) {
            // 需要先清空原有的数据
            this.bodys[rowIndex][itemC.key] = '';
            // headers.
            const arrOption = data[itemC.value].split(',');
            const arr = [];
            arrOption.forEach(itemCC => {
              arr.push({
                lable: itemCC,
                value: itemCC
              });
            });
            linkObj.opintion = arr;
            // 只有一个选项则默认为该选项
            if (arr.length === 1) {
              this.bodys[rowIndex][itemC.key] = arrOption[0];
            } else {
              this.bodys[rowIndex][itemC.key] = '';
            }
          } else {
            this.bodys[rowIndex][itemC.key] = data[itemC.value];
          }
        });
      this.$forceUpdate();
    },
    changeItemOption(payload) {
      const { item, option } = payload;
      item.opintion = option;
      // item.opintion = option;
    },
    // 特殊url请求,item为当前操作对象,value为数据,index为行数
    getUrlRequire(item, value, index) {
      // 改表单是否有other?
      if (this.otherUrlRequire.length) {
        const { dataIndex } = item;
        // 改操作对象是否为other需要的dataindex
        if (this.otherUrlDataindex.includes(dataIndex)) {
          for (const i in this.otherUrlParams[index]) {
            let otheAllParams = true;
            this.otherUrlParams[index][i][dataIndex] &&
              (this.otherUrlParams[index][i][
                dataIndex
              ].value = value);
            for (const k in this.otherUrlParams[index][i]) {
              !this.otherUrlParams[index][i][k]['value'] &&
                (otheAllParams = false);
            }
            const findObj = this.otherUrlRequire.find(
              v => v.dataIndex === i
            );
            if (
              otheAllParams &&
              findObj &&
              findObj.componentType !== 'select'
            ) {
              const otherKey = this.otherUrlParams[index][i];
              const endREquestPayload = dealRequestData(
                findObj.focusUrlParams,
                otherKey
              );
              getCommonData(endREquestPayload, findObj.focusUrl).then(
                ({ data }) => {
                  const { success, message } = data;
                  if (success) {
                    this.bodys.forEach(v => {
                      v[findObj.dataIndex] = data.data.result;
                    });
                  } else {
                    this.bodys.forEach(v => {
                      v[findObj.dataIndex] = '';
                    });
                    this.$message.error(message);
                  }
                }
              );
            }
          }
          this.$forceUpdate();
        }
      }
    },
    toggleFlag(item) {
      this.$set(item, 'myToggleFlag', !item.myToggleFlag);
      this.$forceUpdate();
    },
    handleCancel() {
      // 查看详情直接关
      this.$confirm('确认关闭？')
        .then(_ => {
          this.close();
        })
        .catch(_ => {});
    },
    close() {
      this.$emit('update:isShow', false);
    },
    handleOk() {
      // 验证必填字段
      let require;
      for (let i = 0; i < this.requireArr.length; i++) {
        for (let f = 0; f < this.bodys.length; f++) {
          if (!this.bodys[f][this.requireArr[i].dataIndex]) {
            this.$message.error(`第${f + 1}行的${this.requireArr[i].title}未填写`);
            require = true;
            return;
          }
        }
      }
      if (require) return;
      const { menuId } = this.$route.query;
      // 编辑的数据
      const editArr = [];
      const editIndex = [];
      this.bodys.forEach((item, i) => {
        // 没有guid走cread
        if (!item.formguid && !item.FORMGUID) {
          // 判断是否编辑
          let edit;
          for (const key in item) {
            if (item[key] !== this.oldBody[i][key]) {
              edit = true;
            }
          }
          edit && editArr.push({
            menuId,
            bodyData: [
              {
                data: [
                  {
                    ...item,
                    option: 'create'
                  }
                ],
                tableId: this.tableId
              }
            ]
          }) && editIndex.push(i);
        } else {
          // 判断是否编辑,并找出编辑的字段
          const updataObj = {};
          let edit;
          for (const key in item) {
            if (item[key] !== this.oldBody[i][key]) {
              edit = true;
              updataObj[key] = item[key];
            }
          }
          edit && editArr.push({
            formGuid: item.formGuid || item.FORMGUID,
            bodyData: [
              {
                data: [
                  {
                    ...updataObj,
                    option: 'update',
                    rowNum: item.ROW_NUM
                  }
                ],
                tableId: this.tableId
              }
            ]
          }) && editIndex.push(i);
        }
      });
      const promise = [];
      if (editArr.length) {
        editArr.forEach(item => {
          promise.push(this.save(item));
        });
      }
      if (promise.length) {
        Promise.all(promise).then(res => {
        // 失败的接口的索引
          const error = [];
          res.forEach((item, i) => {
            !item.success && error.push(editIndex[i] + 1);
          });
          if (error.length) {
            const bodys = [];
            const oldBody = [];
            error.forEach(i => {
              bodys.push(this.bodys[i - 1]);
              oldBody.push(this.oldBody[i - 1]);
            });
            this.oldBody = oldBody;
            this.bodys = bodys;
            this.$message.error(`第${error.join()}行编辑失败`);
          } else {
            this.$message.success('批量编辑成功');
            this.$emit('update:isShow', false);
          }
          // 表格刷新
          this.$emit('updataTable');
        });
      } else {
        this.$emit('update:isShow', false);
      }
    },
    save(data) {
      return new Promise((resolve) => {
        saveDynamicForm(data).then(res => {
          resolve(res);
        });
      });
    }
  }
};
</script>

<style lang="scss" scoped>

.myEllipsis /deep/ input {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.prefix_icon {
  cursor: pointer;
  font-size: 12px;
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  // overflow: hidden;

  > div {
    height: 33%;
    position: relative;
    // top: -5px;
    color: #fff;
    // position: absolute;
  }
    .prefix_icon_bg {
      height: 35px;
      width: 30px;
      position: absolute;
      background-color: #1492FF;
      top: 2px;
      border-radius: 2px;
    }
}
.prefix_icon_search{
  > div {
    top: -5px;
    // position: absolute;
  }
}
.FPText{
  height: 400px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
  color: #1492FF;
}
.el-icon-s-open{
  color: #cccccc;
  transform:rotate(180deg);
}
.active-edit{
  cursor: pointer;
  color: #1492FF;
}
</style>

